<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>事件生成</title>
</head>
<body>
<script>
  /*
  * 事件生成的原理和消息订阅发布的原理差不多
  * 将事件名/消息名作为对象的属性名，消息/事件 的回调函数作为属性值
  * 消息的订阅/生成事件  本质就是为对象身上天加一个新的属性
  *
  * 消息的发布/事件的触发的本质就是 去除对象中消息/事件对应的回调函数进行执行
  *
  * 取消订阅和就是删除对象的属性
  *
  *
  * */


  /*
  *
  *
  * */
  let eventMixin ={
    on(event,callback){
      if (!this._eventHandler){
          this._eventHandler ={}
      }
      if (!this._eventHandler[event]){
        this._eventHandler[event] = []
      }
      this._eventHandler[event].push(callback)
    },

    trigger(event,...args){
     if (!this._eventHandler?.[event]) return

      for (let handler of this._eventHandler[event]) {
           handler.apply(this,args)
      }


    },

    off(event,callback){
      let handlers =this._eventHandler?.[event]
      if (!handlers) return
      if (!callback){
      delete  this._eventHandler[event]
      }else{

        for (let i = 0; i < handlers; i++) {
          if (handlers[i] === callback){
            handlers.splice(--i,1)
          }
        }
      }



    }


  }

 class UI{
   constructor(x,y) {
     this.x =x
     this.y = y
   }
   print(){
     console.log(this.x,this.y);
   }
 }

 class UserUI extends UI{
    constructor(x,y) {
      super(x,y);
    }

    draw(){
      console.log(`draw: ${this.x} --->  ${this.y}`);
    }
 }

 /*
 * 使用mixin合成事件
 *
 * */
 Object.assign(UserUI.prototype,eventMixin)

let userUI = new UserUI(1,2);
  userUI.draw()
  userUI.on("select",(x,y) =>{
    console.log(x+y);
  })

  setTimeout(()=>{
    userUI.trigger("select",100,200)
  },2000)


</script>
</body>
</html>